package com.ihr360.payroll.service.salarytasklet;

import com.alibaba.fastjson.JSONObject;
import com.ihr360.commons.lang.CollectionUtils;
import com.ihr360.excel.view.ExcelColumnDef;
import com.ihr360.excel.view.ExcelRowDef;
import com.ihr360.excel.view.ExcelSheetDef;
import com.ihr360.excel.view.IExcelRowDef;
import com.ihr360.expr.parser.ExprToken;
import com.ihr360.payroll.dao.PayPeriodTermRepository;
import com.ihr360.payroll.dao.SalaryCalcMiddleDataRepository;
import com.ihr360.payroll.dao.SystemSalaryFieldRepository;
import com.ihr360.payroll.model.dto.salary.meta.system.SystemSalaryField;
import com.ihr360.payroll.model.dto.salary.task.period.PayPeriodTerm;
import com.ihr360.payroll.model.dto.salary.task.period.SalaryCalcMiddleData;
import com.ihr360.payroll.model.dto.salary.task.period.embeddable.CalcMiddleRow;
import com.ihr360.payroll.service.reference.SalaryReferenceService;
import com.ihr360.payroll.service.reference.impl.SalaryReferenceServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class SalaryCalcMiddleDataServiceImpl implements SalaryCalcMiddleDataService {

    @Autowired
    private SalaryCalcMiddleDataRepository salaryCalcMiddleDataRepository;

    @Autowired
    private SalaryReferenceService salaryReferenceService;

    @Override
    public ExcelSheetDef<String> loadMiddleToSheet(Long termId) {

        List<SalaryCalcMiddleData> data = salaryCalcMiddleDataRepository.findByIdTermId(termId);

        Set<String> columnKeys = new HashSet<>();
        List<IExcelRowDef<String>> rowDefs = new ArrayList<>();

        if (CollectionUtils.isNotEmpty(data)) {
            CalcMiddleRow middleRow = data.get(0).getData();
            Map<String, String> values = middleRow.getValues();
            Map<String, String> phasedVariables = middleRow.getPhasedVariables();
            Map<String, String> personalVariables = middleRow.getPersonalVariables();
            Map<String, String> variables = middleRow.getVariables();

            if (CollectionUtils.isNotEmpty(values)) {
                columnKeys.addAll(values.keySet());
            }
            if (CollectionUtils.isNotEmpty(phasedVariables)) {
                columnKeys.addAll(phasedVariables.keySet());
            }
            if (CollectionUtils.isNotEmpty(personalVariables)) {
                columnKeys.addAll(personalVariables.keySet());
            }

            if (CollectionUtils.isNotEmpty(variables)) {
                columnKeys.addAll(variables.keySet());
                Map<String, String> row1 = new HashMap<>();
                Map<String, String> row2 = new HashMap<>();
                for (Map.Entry<String, String> entry : variables.entrySet()) {
                    String variableValue = entry.getValue();
                    String variableKey = entry.getKey();
                    JSONObject jsonObject = null;
                    String parsedFormula = variableValue;
                    try {
                        jsonObject = salaryReferenceService.parseCodeToIdeographicFormular("=" + variableValue);
                        Object o = jsonObject.get(SalaryReferenceServiceImpl.FORMULAR_KEY);
                        parsedFormula = o.toString();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    row1.put(variableKey, parsedFormula);
                    row2.put(variableKey, variableValue);
                }
                ExcelRowDef rowDef1 = new ExcelRowDef(row1);
                rowDefs.add(rowDef1);
                ExcelRowDef rowDef2 = new ExcelRowDef(row2);
                rowDefs.add(rowDef2);
            }

            for (SalaryCalcMiddleData row : data) {
                middleRow = row.getData();
                values = middleRow.getValues();
                phasedVariables = middleRow.getPhasedVariables();
                personalVariables = middleRow.getPersonalVariables();
                if (middleRow != null) {
                    Map<String, String> rowValues = new HashMap<>();
                    rowValues.put("staffName", row.getStaffName());
                    if (CollectionUtils.isNotEmpty(values)) {
                        rowValues.putAll(values);
                    }
                    if (CollectionUtils.isNotEmpty(phasedVariables)) {
                        rowValues.putAll(phasedVariables);
                    }
                    if (CollectionUtils.isNotEmpty(personalVariables)) {
                        rowValues.putAll(personalVariables);
                    }
                    ExcelRowDef rowDef = new ExcelRowDef(rowValues);
                    rowDefs.add(rowDef);
                }
            }

        }
        List<ExcelColumnDef> columnDefs = columnKeys.stream().map(s -> {
                    JSONObject jsonObject = null;
                    String paredFormula = s;
                    try {
                        jsonObject = salaryReferenceService.parseCodeToIdeographicFormular(ExprToken.EQUAL.val + s);
                        Object o = jsonObject.get(SalaryReferenceServiceImpl.FORMULAR_KEY);
                        paredFormula = o.toString();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if (paredFormula.startsWith(ExprToken.EQUAL.val)) {
                        paredFormula = paredFormula.substring(1);
                    }
                    return new ExcelColumnDef(s, paredFormula);
                }
        ).collect(Collectors.toList());
        columnDefs.sort((s1, s2) -> {
            if (s1.equals(s2)) {
                return 0;
            }
            return s1.getName().compareTo(s2.getName());
        });
        columnDefs.add(0, new ExcelColumnDef("staffName", "姓名"));
        return new ExcelSheetDef<>("test", columnDefs, rowDefs, true);
    }

}